/** Administrate the different parts of the compiler.
 * @file 
 * @author Jeremy Schultz
 *
 * Provides error reporting methods
 */

#ifndef	__ADMINISTRATION_H_
#define	__ADMINISTRATION_H_

#include <iostream>
#include "Token.h"
#include "Word.h"
#include "Numeric.h"

using namespace std;
class Parser;

/** Administrates the compiler steps.
 * Currently, this just provides various error reporting methods
 */
class Administration	{

	private:
		ostream *oBuffer;   /**< output buffer */
		int prevErrorLine;	/**< Previous Error Line */
		bool errorOccurred;   /**< store if an error occurred */

		/** Helper Function for Parser Errors.
		 * Displays the current Token for parser errors
		 * @param t	The current Token to display
		 */ 
		 void Administration::butReadA(Token* t);

	public:
		/** Constructor.
		 */
		Administration(ostream &_oBuffer);

		//-----------------------------------------------------------------------------
		// Emit
		//-----------------------------------------------------------------------------
		
		/** Emit intermediate code.
		 * @param code	The code word to emit.
		 */
		void emit(string code);

		/** Emit intermediate code.
		 * @param code	The code word to emit.
		 * @param arg1  An integer argument to emit
		 */
		void emit(string code, int arg1);

		/** Emit intermediate code.
		 * @param code	The code word to emit.
		 * @param arg1  An integer argument to emit
		 * @param arg2  An integer argument to emit
		 */
		void emit(string code, int arg1, int arg2);

		/** Error Occurred?.
		 * @return True if an error has occurred, else false
		 */
		bool ErrorOccurred();


		//-----------------------------------------------------------------------------
		// Parser Errors: errorMatch
		//-----------------------------------------------------------------------------
		
		/** Parser Error Handler.
		 * Handles Word Errors
		 * @param lex	    The lexeme that was expected
		 * @param curToken	The current Token
		 * @param lineNum	The current line being scanned
		 */
		void errorMatch(string lex, Token* curToken, int lineNum);

		/** Parser Error Handler.
		 * Handles Numeric Errors
		 * @param curToken	The current Token
		 * @param lineNum	The current line being scanned
		 */
		void errorMatch(Token* curToken, int lineNum);


		/** Parser Error Handler.
		 * Handles Symbol Errors
		 * @param type		The symbol type that was expected
		 * @param curToken	The current Token
		 * @param lineNum	The current line being scanned
		 */
		void errorMatch(Token::TokenType type, Token* curToken, int lineNum);
		
		//-----------------------------------------------------------------------------
		// Parser Errors: 
		//-----------------------------------------------------------------------------
		/** Parser Error Handler.
		 * Handles undefined word
		 * @param word		The undefined word
		 * @param lineNum	The current line being scanned
		 */
		void errorUndefined(string word, int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorInvalidValue(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorMaxBlocks(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorDefinition(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorVariableDef(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorStatement(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorMismatchedTypes(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorUnbalanced(int lineNum);

		/** Handle Error
		 * @param lex	   The lexeme that is not a procedure
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorNotProcedure(string lex, int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorNotBoolean(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorNotInteger(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorInvalidPrimOper(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorInvalidAddOper(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorInvalidRelatOper(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorInvalidMultiOper(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorConstant(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 */
		void errorFactor(int lineNum);

		/** Handle Error
		 * @param lineNum  The line number that the error occurred.
		 * @param maxLabels The max labels 
		 */
		void errorLabelMax(int maxLabels, int lineNum);

		/** Handler Error
		 * @param lex	The word previously defined
		 * @param lineNum	The current line being scanned
		 */
		void errorInsert(string lex, int lineNum);

		/** Parser Error Handler.
		 * Handles Definition Errors
		 * @param lineNum	The current line being scanned
		 * @param errMessage The error Message to display
		 */
		void Administration::error(int lineNum, string errMessage);


	
	
		//-----------------------------------------------------------------------------
		// Scanner Errors
		//-----------------------------------------------------------------------------
	
		/** Scanner Error Handler.
		 * Handles Invalid character Errors
		 * @param lineNum	The current line being scanned
		 * @param c The invalid character
		 */
		void Administration::errorInvalidChar(int lineNum, char c);

		/** Scanner Error Handler.
		 * Handles Invalid character for assign ':='
		 * @param lineNum	The current line being scanned
		 * @param c The invalid character
		 */
		void Administration::errorBadAssign(int lineNum, char c);

		/** Scanner Error Handler.
		 * Handles Invalid Number Errors
		 * @param lineNum	The current line being scanned
		 * @param n The number 
		 * @param c The invalid character
		 */
		void Administration::errorBadNumber(int lineNum, int n, char c);


		/** Scanner Error Handler.
		 * Handles Unexpected EOF
		 * @param lineNum	The current line being scanned
		 */
		void Administration::errorEOF(int lineNum);


};
#endif

